use crate::cblash_h;
use common::complex::complex::Complex;

/*
cblas_caxpy(_:_:_:_:_:_:)
Computes a constant times a vector plus a vector (single-precision complex).

from: https://developer.apple.com/documentation/accelerate/1513196-cblas_caxpy

Parameters
N
Number of elements in the vectors.

alpha
Scaling factor for the values in X.

X
Input vector X.

incX
Stride within X. For example, if incX is 7, every 7th element is used.

Y
Input vector Y.

incY
Stride within Y. For example, if incY is 7, every 7th element is used.
 */

pub fn cblas_caxpy(
    N: i32,
    alpha: &Complex,
    X: &Vec<Complex>,
    incX: i32,
    Y: &mut Vec<Complex>,
    incY: i32,
) {
    // #include "source_axpy_c.h"

    /*
    if (fabs(alpha_real) == 0 && fabs(alpha_imag) == 0) {
      return;
    }
     */
    if alpha.near_zero() {
        return;
    }
    if N < 1 {
        return;
    }
    let len_x = X.len();
    let len_y = Y.len();

    let ix = cblash_h::offset(N as usize, incX);
    let iy = cblash_h::offset(N as usize, incY);

    if len_x < ix.len_mustbe {
        panic!("cblas_caxpy: X 长度 {len_x} < 应该的长度 {}", ix.len_mustbe);
    }
    if len_y < iy.len_mustbe {
        panic!("cblas_caxpy: Y 长度 {len_y} < 应该的长度 {}", iy.len_mustbe);
    }

    let alpha_real = alpha.real;
    let alpha_imag = alpha.imag;

    for idx in 0..ix.indices.len() {
        let item_x = X.get(ix.indices[idx]).expect("Unreachable");
        let item_y = Y.get_mut(iy.indices[idx]).expect("Unreachable");

        let x_real = item_x.real;
        let x_imag = item_x.imag;
        item_y.real += alpha_real * x_real - alpha_imag * x_imag;
        item_y.imag += alpha_real * x_imag + alpha_imag * x_real;
    }
}

